// 给你一个数组 nums 和一个值 val，你需要 原地 移除所有数值等于 val 的元素，并返回移除后数组的新长度。
// 不要使用额外的数组空间，你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
// 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
//  
// 说明:
// 为什么返回数值是整数，但输出的答案是数组呢?
// 请注意，输入数组是以「引用」方式传递的，这意味着在函数里修改输入数组对于调用者是可见的。
// 你可以想象内部操作如下:
// // nums 是以“引用”方式传递的。也就是说，不对实参作任何拷贝
// int len = removeElement(nums, val);
// // 在函数里修改输入数组对于调用者是可见的。
// // 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
// for (int i = 0; i < len; i++) {
//     print(nums[i]);
// }

/**
 * 思路:
 *      遍历数组，初始化两个变量0：p和q,p用来遍历数组，q用来记录次数
 *      当nums[p] === val时     p++ ,q无操作
 *      当nums[p] !== val时     p++ ,nums[q++] = nums[p];
 *                              这时候会修改nums的值 并且q的值就是次数 
 * @param nums [1,0,2,4] 
 * @param val 2
 * @returns 
 * 循环次数 p    q(结束时)  nums[p]     val        nums                nums[q]
 * 1       0    1             1        false      [1,0,2,4]           [1]
 * 2       1    2             0        false      [1,0,2,4]           [1.0]
 * 3       2    2             2        true       [1,0,2,4]           [1,0]
 * 4       3    3             4        false      [1,0,4,4]           [1,0,4]
 */


function removeElement(nums: number[], val: number): number {
    let p = 0;
    let q = 0;
    while (p < nums.length) {
        if (nums[p] !== val) {
            nums[q++] = nums[p];
        }
        p++;
    };
    return q;
};